#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<jsoncpp/json/json.h>
namespace ser_and_dser
{
//#define MYSELF 1
#define SPACE " "
#define SPACE_LEN strlen(SPACE)
#define SIZE 1024
#define SEP "\r\n"
#define SEP_LEN strlen(SEP)

    class Request
    {
    public:
        // 序列化
        std::string Serialize() // 数据类型变为字符串
        {
#ifdef MYSELF
            // 自己定义
            std::string s;
            s = std::to_string(_x);
            s += SPACE;
            s += _op;
            s += SPACE;
            s += std::to_string(_y);
            return s;
#else
            // 使用库函数
            Json::Value root;
            root["x"] = _x;
            root["op"] = _op;
            root["y"] = _y;
            Json::FastWriter writer;
            return writer.write(root);

#endif
        }
        // 反序列化
        bool Deserialize(const std::string &s) // 字符串变为数据类型
        {
#ifdef MYSELF
            // 自己定义
            std::size_t left = s.find(SPACE);
            if (left == std::string::npos)
                return false;
            std::size_t right = s.rfind(SPACE);
            if (right == std::string::npos)
                return false;
            _x = std::atoi(s.substr(0, left).c_str());
            _y = std::atoi(s.substr(right + SPACE_LEN).c_str());
            if (left + SPACE_LEN > s.size())
                return false;
            else
                _op = s[left + SPACE_LEN];
            return true;
#else
            // 使用库函数
            Json::Value root;
            Json::Reader reader;
            reader.parse(s,root);
            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _op = root["op"].asInt();
            return true;
#endif
        }
        Request() {}
        Request(int x, int y, int op) : _x(x), _y(y), _op(op) {}
        ~Request() {}

    public:
        int _x;
        int _y;
        char _op;
    };

    class Response
    {
    public:
        std::string Serlize()
        {
#ifdef MYSELF
            std::string s;
            s = std::to_string(_flag);
            s += SPACE;
            s += std::to_string(_res);
            return s;
#else
            // 使用库函数
            Json::Value root;
            root["flag"] = _flag;
            root["res"] = _res;
            Json::FastWriter writer;
            return writer.write(root);
#endif
        }
        bool Deserlize(std::string &s)
        {
#ifdef MYSELF
            std::size_t pos = s.find(SPACE);
            if (pos == std::string::npos)
                return false;
            _flag = atoi(s.substr(0, pos).c_str());
            _res = atoi(s.substr(pos + SPACE_LEN).c_str());
            return true;
#else
            // 使用库函数
            Json::Value root;
            Json::Reader reader;
            reader.parse(s,root);
            _flag = root["flsg"].asInt();
            _res = root["res"].asInt();
            return true;
#endif
        }
        Response() {}
        Response(int res, int flag) : _res(res), _flag(flag) {}
        ~Response() {}

    public:
        int _res;  // 结果
        int _flag; // 结果的状态码
    };

    bool Recv(int sock, std::string *out)
    {
        char buffer[SIZE];
        ssize_t s = recv(sock, buffer, sizeof(buffer) - 1, 0);
        if (s > 0)
        {
            buffer[s] = 0;
            *out += buffer;
        }
        else if (s == 0)
        {
            // std::cout<<"client quit"<<std::endl;
            return false;
        }
        else
        {
            // std::cout<<"recv error"<<std::endl;
            return false;
        }
        return true;
    }
    void Send(int sock, const std::string str)
    {
        //std::cout << "send in" << std::endl;
        int n = send(sock, str.c_str(), str.size(), 0);
        if (n < 0)
        {
            std::cout << "send error" << std::endl;
        }
    }
    // 编码：加上报文，保证每次传输的都是这种格式： length\r\nx_ op_ y_\r\n
    std::string Encode(std::string &buffer)
    {
        std::string new_packag = std::to_string(buffer.size());
        new_packag += SEP;
        new_packag += buffer;
        new_packag += SEP;
        return new_packag;
    }
    // 解码：去掉报文，保证每次读取的都是完整的一次计算信息：x_ op_ y_
    std::string Decode(std::string &buffer)
    {
        std::size_t pos = buffer.find(SEP);
        if (pos == std::string::npos)
            return "";
        int size = atoi(buffer.substr(0, pos).c_str());
        int surplus = buffer.size() - pos - 2 * SEP_LEN;
        if (surplus >= size) // 剩下的字符长度足够一个完整的计算信息
        {
            buffer.erase(0, pos + SEP_LEN);
            std::string s = buffer.substr(0, size);
            buffer.erase(0, size + SEP_LEN);
            return s;
        }
        else
            return "";
    }
}